package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersRejectionDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.enumeration.OrderStatus;
import com.sky.enumeration.PayStatus;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.OrderDetailPageVO;
import com.sky.vo.OrderPageVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private AddressBookMapper addressBookMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Override
    @Transactional
    public @Validated
    OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        // 地址以判断不为空，购物车不能为空
        // TODO 需要判断配送范围，不会写
        //判断用户有没有购物车
        // 往订单表orders中插入一条记录，并且需要往order_detail中插入一条或多条记录
        //异常情况的处理（收货地址为空、超出配送范围、购物车为空）
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        Long userId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);

        //查询当前用户的购物车数据
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.getList(shoppingCart);
        if (shoppingCartList == null || shoppingCartList.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //构造订单数据
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, order);
        order.setPhone(addressBook.getPhone());
        order.setAddress(addressBook.getDetail());
        order.setConsignee(addressBook.getConsignee());
        order.setNumber(String.valueOf(System.currentTimeMillis()));
        order.setUserId(userId);
        order.setStatus(Orders.PENDING_PAYMENT);
        order.setPayStatus(Orders.UN_PAID);
        order.setOrderTime(LocalDateTime.now());

        //向订单表插入1条数据
        orderMapper.insert(order);

        //订单明细数据
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(order.getId());
            orderDetailList.add(orderDetail);
        }

        //向明细表插入n条数据
        orderDetailMapper.insertBatch(orderDetailList);

        //清理购物车中的数据
        shoppingCartMapper.delByUserId(userId);

        //封装返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(order.getId())
                .orderNumber(order.getNumber())
                .orderAmount(order.getAmount())
                .orderTime(order.getOrderTime())
                .build();

        return orderSubmitVO;
    }

    @Override
    public PageResult historyOrders(OrdersPageQueryDTO dto) {
        // 开启分页
        PageHelper.startPage(dto.getPage(), dto.getPageSize());

        // 查询订单基本信息，根据下单时间降序排序
        Page<Orders> page = orderMapper.page(dto);

        // 构建返回对象
        List<OrderPageVO> vos = page.getResult().stream().map(order -> {
            OrderPageVO vo = new OrderPageVO();
            BeanUtils.copyProperties(order, vo);    // 订单基本信息拷贝给返回对象

            // 构建查询参数
            OrderDetail queryOrderDetail = OrderDetail.builder()
                    .orderId(order.getId())     // 订单id
                    .build();
            List<OrderDetail> orderDetailList = orderDetailMapper.list(queryOrderDetail);            // 查询订单明细

            // 组装vo
            vo.setOrderDetailList(
                    orderDetailList.stream().map(orderDetail -> {
                        OrderDetailPageVO orderDetailPageVO = new OrderDetailPageVO();
                        BeanUtils.copyProperties(orderDetail, orderDetailPageVO);
                        return orderDetailPageVO;
                    }).collect(Collectors.toList())
            );

            return vo;
        }).collect(Collectors.toList());

        return PageResult.builder()
                .total(page.getTotal())
                .records(vos)
                .build();
    }

    @Override
    public OrderPageVO orderInfo(Long id) {

        Orders order = orderMapper.getById(id);     // 根据id查询

        // 构建返回对象
            OrderPageVO vo = new OrderPageVO();
            BeanUtils.copyProperties(order, vo);    // 订单基本信息拷贝给返回对象

            // 构建查询参数
            OrderDetail queryOrderDetail = OrderDetail.builder()
                    .orderId(order.getId())     // 订单id
                    .build();
            List<OrderDetail> orderDetailList = orderDetailMapper.list(queryOrderDetail);            // 查询订单明细

            // 组装vo
            vo.setOrderDetailList(
                    orderDetailList.stream().map(orderDetail -> {
                        OrderDetailPageVO orderDetailPageVO = new OrderDetailPageVO();
                        BeanUtils.copyProperties(orderDetail, orderDetailPageVO);
                        return orderDetailPageVO;
                    }).collect(Collectors.toList())
            );

        return vo;
    }

    @Override
    public void cancelOrder(Long id) {

        // 构建修改参数
        Orders update = Orders.builder()
                .id(id)                             // 订单id
                .status(6)                          // 订单状态
                .cancelTime(LocalDateTime.now())    // 取消时间
                .cancelReason(null)                 // 取消原因
                .build();

        orderMapper.update(update);
    }

    @Transactional
    @Override
    public OrderSubmitVO again(Long id) {

        // 获取需要复制的信息
        OrderPageVO vo = orderInfo(id);
        Orders order = new Orders();
        BeanUtils.copyProperties(vo, order);
        order.setStatus(Orders.PENDING_PAYMENT);        // 设置订单状态
        order.setPayStatus(Orders.UN_PAID);         // 设置支付状态
        order.setOrderTime(LocalDateTime.now());        // 设置下单时间
        order.setNumber(String.valueOf(System.currentTimeMillis()));        // 设置订单号

        orderMapper.insert(order);      //向订单表插入1条数据

        //向明细表插入n条数据
        List<OrderDetailPageVO> orderDetailVOList = vo.getOrderDetailList();
        List<OrderDetail> orderDetailList = orderDetailVOList.stream().map(orderDetailPageVO -> {

            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(orderDetailPageVO, orderDetail);
            orderDetail.setOrderId(order.getId());      // 设置新订单id

            return orderDetail;
        }).collect(Collectors.toList());
        orderDetailMapper.insertBatch(orderDetailList);

        //封装返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(order.getId())
                .orderNumber(order.getNumber())
                .orderAmount(order.getAmount())
                .orderTime(order.getOrderTime())
                .build();

        return orderSubmitVO;
    }

    @Override
    public void takeOrder(Long id) {

        // 构建修改参数
        Orders update = Orders.builder()
                .id(id)                             // 订单id
                .status(OrderStatus.OK_TAKE.getValue())                          // 订单状态
                .deliveryStatus(1)          // 配送状态
                .build();

        orderMapper.update(update);
    }

    @Override
    public void rejection(OrdersRejectionDTO dto) {

        // 构建修改参数
        Orders update = Orders.builder()
                .id(dto.getId())                             // 订单id
                .status(OrderStatus.CANCEL.getValue())                          // 订单状态
                .rejectionReason(dto.getRejectionReason())      // 拒单原因
                .payStatus(PayStatus.REFUND.getValue())     // 支付状态
                .build();

        orderMapper.update(update);
    }

    @Override
    public void delivery(Long id) {

        // 构建修改参数
        Orders update = Orders.builder()
                .id(id)                             // 订单id
                .status(OrderStatus.DELIVERING.getValue())                          // 订单状态
//                .deliveryStatus(1)              //配送状态
                .estimatedDeliveryTime(LocalDateTime.now().plusSeconds(1800))       // 设置预送达时间
                .build();

        orderMapper.update(update);
    }

    @Override
    public void complete(Long id) {

        // 构建修改参数
        Orders update = Orders.builder()
                .id(id)                             // 订单id
                .status(OrderStatus.OK.getValue())                          // 订单状态
                .deliveryTime(LocalDateTime.now())       // 设置预送达时间
                .build();

        orderMapper.update(update);
    }

    @Override
    public OrderStatisticsVO statistics() {

        List<Orders> orders = orderMapper.list();

        // 过滤待派送
        List<Orders> okTakeList = orders.stream().filter(order -> OrderStatus.OK_TAKE.getValue() == order.getStatus()).collect(Collectors.toList());

        // 过滤派送中
        List<Orders> deliveringList = orders.stream().filter(order -> OrderStatus.DELIVERING.getValue() == order.getStatus()).collect(Collectors.toList());

        // 过滤待接单
        List<Orders> waitTakeList = orders.stream().filter(order -> OrderStatus.WAIT_TAKE.getValue() == order.getStatus()).collect(Collectors.toList());

        return OrderStatisticsVO.builder()
                .confirmed(okTakeList.size())
                .deliveryInProgress(deliveringList.size())
                .toBeConfirmed(waitTakeList.size())
                .build();
    }
}
